/*  
  -- The Lime II Project -- 

  A tuplespaces-based middleware for coordinating agents and mobile hosts.
  Copyright (C) 2005.
  Gian Pietro Picco, Amy L. Murphy, Lorenzo Bellini.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received this copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
*/

package lime2.ca;
import lime2.*;
import java.io.Serializable;
import java.util.HashSet;

/**
 * Interface towards the lowest level of the communication layer.
 * <br>
 * The lowest layer could be plain unicast/multicast TCP/IP, content-based/subject-based publish-subscribe middleware, 
 * distributed hashtable middleware, etc.. 
 * <br>
 * The communication adapter provides implementation-independent primitives; on top of these standard primitives we
 * design the way Lime interacts with other hosts. 
 * <br>
 * A communication adapter MUST support concurrent access of its methods.
 * <br>
 * Please note that the communication adapters that use multicast (LocalCA, PlainCA) are based on a single multicast 
 * address - an optimization for large scale scenarios would be using a specific multicast address per tuplespace
 * (.. this would require the hosts to agree on the addresses, and still would provide a little improvement wrt a 
 * publish/subscribe based communication adapter, i.e. RedsCA).       
 * 
 * @author Gian Pietro Picco
 * @author Amy Murphy
 * @author Lorenzo Bellini 
 */

public interface ICommunicationAdapter 
{
 /**
  * This method must be called before the communication adapter is used; it performs all the necessary initializations
  * (i.e. starting thread/s, establishing permanent connections, etc..) 
  *
  * @throws LimeCommunicationException
  */
 public void init() throws LimeCommunicationException;	
		
 /**
  * Enables this host to join the system. The serializable object may serve to provide startup information for the 
  * joining process (i.e. a host to attach to in a dispatching tree). Please note that communication exceptions are 
  * not thrown; when this method is invoked, it is guaranteed that the LimeServer will join the system as soon as 
  * possible.
  * 
  * @param info startup information for the joining process
  */	
 public void joinSystem(Serializable info);

 /** 
  * Enables this host to leave the system. Please note that communication exceptions are not thrown; when this method
  * is invoked, it is guaranteed that the LimeServer will eventually leave the system. 
  */
 public void leaveSystem();

 /**
  * Declares that from now on this node is interested in everything that concerns a specific tuplespace. Please note 
  * that communication exceptions are not thrown; when this method is invoked, it is guaranteed that the LimeServer 
  * will join the group as soon as possible.
  * 
  * @param name name of the tuplespace we are interested in
  */ 
 public void joinGroup(String name);
	 
 /**
  * Declares that from now on this node is uninterested in everything that concerns a specific tuplespace. Please note
  * that communication exceptions are not thrown; when this method is invoked, it is guaranteed that the LimeServer 
  * will eventually leave the group.
  * 
  * @param name name of the tuplespace we are no more interested in
  */ 
 public void leaveGroup(String name);	

 /**
  * Sends an operation request to all the group members.
  * 
  * @param name name of the destination tuplespace 
  * @param d operation descriptor
  * @throws LimeCommunicationException
  */
 public void sendOp(String name, RemoteOp d) throws LimeCommunicationException; 

 /**
  * Sends an operation request to a specific host.
  * 
  * @param host destination host
  * @param d operation descriptor
  * @throws LimeCommunicationException
  */
 public void sendOp(LimeServerID host, RemoteOp d) throws LimeCommunicationException;
 
 /**
  * Sends an operation through multicast to a collection of specified hosts
  * 
  * @param host destination hosts
  * @return the hosts set to which this multicast directly sends 
  * @param d operation descriptor
  * @throws LimeCommunicationException
  */
 public HashSet<LimeServerID> multicast(LimeServerID[] hosts, RemoteOp d) throws LimeCommunicationException;
 
 /**
  * Sends an operation through multicast to all engageged hosts
  * @param d operation descriptor
  * @return the hosts set to which this multicast directly sends 
  * @throws LimeCommunicationException
  * @author Xing Jiankuan
  */
 public HashSet<LimeServerID> multicast(RemoteOp d) throws LimeCommunicationException;

 /**
  * Sends a reaction registration request to all group members.
  * 
  * @param name name of the destination tuplespace 
  * @param d operation descriptor
  * @throws LimeCommunicationException
  */
 public void sendReaction(String name, RemoteOp d) throws LimeCommunicationException; 

 /**
  * Sends a reaction registration request to a specific host.
  * 
  * @param host destination host
  * @param d operation descriptor
  * @throws LimeCommunicationException
  */
 public void sendReaction(LimeServerID host, RemoteOp d) throws LimeCommunicationException;
 
 /**
  * Allows to bind a message to a previous operation request (i.e, to gather results).
  * 
  * @param host destination host
  * @param d operation descriptor
  * @throws LimeCommunicationException
  */
 public void sendReply(LimeServerID host, RemoteOp d) throws LimeCommunicationException;
	
 /**
  * Returns a received RemoteOp (FIFO order, blocking).
  * 
  * @return RemoteOp
  */
 public RemoteOp getNextOp();
 
 /**
  * Deactivates the communication layer.
  */
 public void shutdown();
 
 /**
  * Returns whether an host is engaged.
  * 
  * @param host
  * @return <code>true</code> or <code>false</code>
  */
 public boolean queryHost(LimeServerID host);
 
 /**
  * Adds a new (discovered) host.
  * 
  * @param host
  */
 public void addHost(LimeServerID host);
  
 /**
  * Removes a (probable) dead host.
  * 
  * @param host
  */
 public void removeHost(LimeServerID host);
 
}
